package com.xben.ribbonconsumer.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import com.netflix.hystrix.exception.HystrixBadRequestException;
import org.apache.tomcat.jni.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.Future;

/**
 * @Author: xben
 * @Date: 2019/1/22 10:50
 */
@Service
public class UserService {
    @Autowired
    private RestTemplate restTemplate;


    @HystrixCommand
    public Future<User> getUserByIdAsync(final String id) {
        return new AsyncResult<User>() {
            @Override
            public User invoke() {
                return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id);
            }
        };
    }

    /**
     * 同步执行
     */
    @CacheResult(cacheKeyMethod = "getUserByIdCacheKey")
    @HystrixCommand(fallbackMethod = "defaultUser", ignoreExceptions = HystrixBadRequestException.class, commandKey = "getUserById", groupKey = "UserGroup",
            threadPoolKey = "getUserByIdThread")
    public User getUserById(@CacheKey("id") Long id) {
        return restTemplate.getForObject("http://USER-SERVICE/users/{1}"
                , User.class, id);
    }

    private Long getUserByIdCacheKey(Long id) {
        return id;
    }

    @HystrixCommand(fallbackMethod = "defaultUserSec")
    public User defaultUser() {
        return new User();
    }

    public User defaultUserSec() {
        return new User();
    }

    @HystrixCommand(fallbackMethod = "fallback1")
    User getById(String id) {
        throw new RuntimeException("getById command failed");
    }

    User fallback1(String id, Throwable e) {
        assert "getById command failed".equals(e.getMessage());
        return null;
    }

    @CacheRemove(commandKey = "getUserById")
    @HystrixCommand
    public User update(@CacheKey("id") User user) {
        return restTemplate.postForObject("http://USER-SERVICE/users", user, User.class);
    }

    @HystrixCommand(commandKey = "helloKey",
            commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",
                    value = "5000"
            )}, threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "20")
    }
    )
    public User goById(Long id) {
        return null;
    }
}
